package com.example.webapp.service.impl;

import com.example.webapp.entity.User;
import com.example.webapp.repository.UserRepository;
import com.example.webapp.security.JwtTokenProvider;
import com.example.webapp.service.UserService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.security.authentication.AuthenticationManager;
import org.springframework.security.authentication.UsernamePasswordAuthenticationToken;
import org.springframework.security.core.Authentication;
import org.springframework.security.core.context.SecurityContextHolder;
import org.springframework.security.crypto.password.PasswordEncoder;
import org.springframework.stereotype.Service;

import java.util.Set;
import java.util.concurrent.ConcurrentHashMap;

@Service
public class UserServiceImpl implements UserService {

    @Autowired
    private UserRepository userRepository;

    @Autowired
    private PasswordEncoder passwordEncoder;

    @Autowired
    private AuthenticationManager authenticationManager;

    @Autowired
    private JwtTokenProvider tokenProvider;

    // 添加token黑名单集合
    private Set<String> tokenBlacklist = ConcurrentHashMap.newKeySet();

    @Override
    public User registerUser(User user) throws Exception {
        if (userRepository.existsByUsername(user.getUsername())) {
            throw new Exception("Username is already taken!");
        }

        if (userRepository.existsByEmail(user.getEmail())) {
            throw new Exception("Email is already registered!");
        }

        user.setPassword(passwordEncoder.encode(user.getPassword()));
        return userRepository.save(user);
    }

    @Override
    public String authenticateUser(String username, String password) throws Exception {
        Authentication authentication = authenticationManager.authenticate(
            new UsernamePasswordAuthenticationToken(username, password)
        );

        SecurityContextHolder.getContext().setAuthentication(authentication);
        return tokenProvider.generateToken(username);
    }

    @Override
    public void invalidateToken(String token) {
        tokenBlacklist.add(token);
    }

    @Override
    public boolean isTokenInvalid(String token) {
        return tokenBlacklist.contains(token);
    }
} 